package TestSystemIO;

import java.awt.CardLayout;
import java.io.*;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import TestSystemClient.Client;
import TestSystemClient.ClientLogin;
import TestSystemClient.ClientMultiplayer;
import TestSystemClient.ClientSinglePlayer;
import TestSystemUtil.Protocol;

public class InputThread extends Thread {
	private BufferedReader input;
	public ArrayList<String> result = new ArrayList<String>();
	public Protocol protocol;
	public JFrame frame;
	Object lockObj;
	String messageFromServer = null;

	public InputThread(BufferedReader input, Object lockObj, String name, Protocol protocol, JFrame frame) {
		super(name);
		this.input = input;
		this.lockObj = lockObj;
		this.protocol = protocol;
		this.frame = frame;
	}
	
	//=================== THREAD RUN METHOD ==================//
	public void run() {
		try {
			while((messageFromServer = input.readLine()) != null) {
				System.out.println("Client recieved from Server: " + messageFromServer);
				if(messageFromServer.equals("INTERRUPT")) break;
				result = protocol.analyseMessageFromServer(messageFromServer);
				switch(protocol.getState()) {
				case Protocol.LOGIN:
					login();
					break;
				case Protocol.SINGLEPLAY:
					singleplay();
					break;
				case Protocol.GROUPPLAY:
					groupplay();
					break;
				}
			}
		} catch (IOException e) {
			Thread.currentThread().interrupt();
		}
	}
	//========================================================//
	
	
	//==== XỬ LÝ THÔNG TIN NHẬN ĐC TẠI  FRAME SINGLE PLAY ====//
	public void singleplay() {
		ClientSinglePlayer tmp = (ClientSinglePlayer) frame;
		switch(result.get(0)) {
		case "HIGHSCORE":
			tmp.tableRecord1.clear();
			for(int i=1; i<result.size(); i++) {
				Vector<String> item = new Vector<String>();	//Tạo một item kiểu array string
				StringTokenizer token = new StringTokenizer(result.get(i), "/");
				while(token.hasMoreTokens()) item.add(token.nextToken());
				tmp.tableRecord1.add(item);							//Add item vào phần info của cả group
			}
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		case "HISTORY":
			tmp.tableRecord2.clear();
			for(int i=1; i<result.size(); i++) {
				Vector<String> item = new Vector<String>();	//Tạo một item kiểu array string
				StringTokenizer token = new StringTokenizer(result.get(i), "/");
				while(token.hasMoreTokens()) item.add(token.nextToken());
				tmp.tableRecord2.add(item);							//Add item vào phần info của cả group
			}
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;	
		case "ONLINE":
			for(int i=1; i<result.size(); i++) tmp.onlineUsers.add(result.get(i));
			tmp.setOnlineUsers(tmp.onlineUsers);
			break;
		case "OFFLINE":
			tmp.onlineUsers.remove(result.get(1));
			tmp.setOnlineUsers(tmp.onlineUsers);
			break;
		case "INVITE":
			CardLayout card = (CardLayout) tmp.playPanel.getLayout();
			tmp.hostname = result.get(1);
			tmp.lblInvite.setText(String.format(tmp.lblInvite.getText(), tmp.hostname, result.get(2)));
			card.show(tmp.playPanel,"card5");
			break;
		case "ACCEPT":
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		case "DECLINE":
			synchronized(lockObj) {
				lockObj.notify();
			}
			JOptionPane.showMessageDialog(tmp, result.get(1) + " declined your invite", "Declined", JOptionPane.INFORMATION_MESSAGE);
			break;
		case "GROUPINFO":											//Khi nhận được tin info về group
			for(int i=1; i<result.size(); i++) {
				ArrayList<String> item = new ArrayList<String>();	//Tạo một item kiểu array string
				String[] split = result.get(i).split("/");			//Tách phần fullname và score bởi dấu / (VD: lequangphu/0 -> lequangphu  0)
				item.add(split[0]);									//Add fullname vào item
				item.add(split[1]);									//Add score vào item
				tmp.groupInfo.add(item);							//Add item vào phần info của cả group
				
			}
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		case "SUCCESS":
		case "ERR":
			Client.messageFromServer = messageFromServer;
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		}
	}
	//========================================================//
	
	
	//=== XỬ LÝ THÔNG TIN NHẬN ĐƯỢC TẠI FRAME CLIENT LOGIN ===//	
	public void login() {
		ClientLogin tmp = (ClientLogin) frame;
		switch(result.get(0)) {
		case "REGISTER":
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		case "ONLINE":
			for(int i=1; i<result.size(); i++) 
				tmp.onlineUsers.add(result.get(i));
			break;
		case "SUCCESS":
		case "ERR":
			tmp.playerInfo = result;
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		}
	}
	// =======================================================//	
	
	
	//=== XỬ LÝ THÔNG TIN NHẬN ĐƯỢC TẠI FRAME MULTIPLAYER ====//	
	public void groupplay() {
		ClientMultiplayer tmp = (ClientMultiplayer) frame;								//Cast JFrame frame về ClientMultiplayer
		switch(result.get(0)) {															//Switch mảnh đầu của tin từ server
		case "ONLINE":
			for(int i=1; i<result.size(); i++) tmp.onlineUsers.add(result.get(i));
			tmp.setOnlineUsers(tmp.onlineUsers);
			break;
		case "OFFLINE":
			tmp.onlineUsers.remove(result.get(1));
			tmp.setOnlineUsers(tmp.onlineUsers);
			break;
		case "ACCEPT":
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		case "DECLINE":
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		case "GROUPINFO":											//Khi nhận được tin info về group
			tmp.groupInfo.clear();
			for(int i=1; i<result.size(); i++) {
				ArrayList<String> item = new ArrayList<String>();	//Tạo một item kiểu array string
				String[] split = result.get(i).split("/");			//Tách phần fullname và score bởi dấu / (VD: lequangphu/0 -> lequangphu  0)
				item.add(split[0]);									//Add fullname vào item
				item.add(split[1]);									//Add score vào item
				tmp.groupInfo.add(item);							//Add item vào phần info của cả group
				
			}
			if(tmp.groupInfo.size() > 1) {
				tmp.setGroupInfo(tmp.groupInfo, tmp.hostname);
			} else {
				tmp.groupNotExist();
			}
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		case "GROUPSTART":											//Tin nhận được khi host click nút Start
			tmp.c.show(tmp.panelPlay, "card3");						//Đổi sang card 3 - panelQuestion
			break;
		case "GROUPQUESTION":
			tmp.t.start();											//Sau tin Groupstart sẽ là tin Groupquestion
			tmp.setQuestion(result);								//Setquestion
			break;
		case "GROUPRESULT":
			tmp.groupResult.clear();
			for(int i=1; i<result.size()-1; i++) {
				Vector<String> item = new Vector<String>();	//Tạo một item kiểu array string
				StringTokenizer token = new StringTokenizer(result.get(i), "/");
				while(token.hasMoreTokens()) item.add(token.nextToken());
				tmp.groupResult.add(item);							//Add item vào phần info của cả group
			}
			tmp.correctAnswer = result.get(result.size()-1);
			tmp.setResultInfo(tmp.groupResult);
			tmp.c.show(tmp.panelPlay, "card4");
			break;
		case "ERR":
			JOptionPane.showMessageDialog(null, result.get(1), "Warning", JOptionPane.WARNING_MESSAGE);
			tmp.list.clearSelection();
			synchronized(lockObj) {
				lockObj.notify();
			}
			break;
		}
	}
	// =======================================================//	
}
